/*
 * Copyright (C) 2017, Ulrich Wolffgang <u.wol@wwu.de> All rights reserved.
 *
 * This software may be modified and distributed under the terms of the BSD 3-clause license. See
 * the LICENSE file for details.
 */

package ling.learn.antlr.cobol85.preprocessor.sub.document.impl;

import java.util.Arrays;
import java.util.List;
import org.antlr.v4.runtime.BufferedTokenStream;
import ling.learn.antlr.cobol85.preprocessor.gen.Cobol85PreprocessorParser.ReplaceClauseContext;

/**
 * A replacement context that defines, which replaceables should be replaced by which replacements.
 */
public class CobolDocumentContext {

  private CobolReplacementMapping[] currentReplaceableReplacements;

  private StringBuffer outputBuffer = new StringBuffer();

  public String read() {
    return outputBuffer.toString();
  }

  /**
   * Replaces replaceables with replacements.
   */
  public void replaceReplaceablesByReplacements(final BufferedTokenStream tokens) {
    if (currentReplaceableReplacements != null) {
      Arrays.sort(currentReplaceableReplacements);

      for (final CobolReplacementMapping replaceableReplacement : currentReplaceableReplacements) {
        final String currentOutput = outputBuffer.toString();
        final String replacedOutput = replaceableReplacement.replace(currentOutput, tokens);

        outputBuffer = new StringBuffer();
        outputBuffer.append(replacedOutput);
      }
    }
  }

  public void storeReplaceablesAndReplacements(final List<ReplaceClauseContext> replaceClauses) {
    if (replaceClauses == null) {
      currentReplaceableReplacements = null;
    } else {
      final int length = replaceClauses.size();
      currentReplaceableReplacements = new CobolReplacementMapping[length];

      int i = 0;

      for (final ReplaceClauseContext replaceClause : replaceClauses) {
        final CobolReplacementMapping replaceableReplacement = new CobolReplacementMapping();

        replaceableReplacement.replaceable = replaceClause.replaceable();
        replaceableReplacement.replacement = replaceClause.replacement();

        currentReplaceableReplacements[i] = replaceableReplacement;
        i++;
      }
    }
  }

  public void write(final String text) {
    outputBuffer.append(text);
  }
}
